﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace LogonDesktopTools
{
    public class WinApi
    {
        public const UInt32 GENERIC_ALL = 0x10000000;

        [DllImport("user32")]
        public static extern IntPtr OpenInputDesktop(UInt32 dwFlags, bool fInherit, UInt32 dwDesiredAccess);

        public const UInt32 MAX_PATH = 256;

        public const int UOI_NAME = 2;

        [DllImport("user32")]
        public static extern bool GetUserObjectInformation(IntPtr hObj, int nIndex, byte[] pvInfo, UInt32 nLength, out UInt32 lpnLengthNeeded);

        [DllImport("user32", SetLastError = true)]
        public static extern bool SetThreadDesktop(IntPtr hDesktop);

        [DllImport("user32")]
        public static extern bool CloseDesktop(IntPtr hDesktop);

        public const UInt32 TOKEN_ALL_ACCESS = 0x000F0000 | 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080 | 0x0100;

        [DllImport("advapi32")]
        public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);

        public const int SecurityImpersonation = 2;

        public const int TokenPrimary = 1;

        [DllImport("advapi32")]
        public static extern bool DuplicateTokenEx(IntPtr hExistingToken, UInt32 dwDesiredAccess, IntPtr lpTokenAttributes, int ImpersonationLevel, int TokenType, out IntPtr phNewToken);

        [DllImport("kernel32")]
        public static extern UInt32 WTSGetActiveConsoleSessionId();

        public const int TokenSessionId = 12;

        [DllImport("advapi32")]
        public static extern bool SetTokenInformation(IntPtr TokenHandle, int TokenInformationClass, ref UInt32 TokenInformation, UInt32 TokenInformationLength);

        public struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public int dwProcessId;
            public int dwThreadId;

            public PROCESS_INFORMATION(bool dummy)
            {
                hProcess = IntPtr.Zero;
                hThread = IntPtr.Zero;
                dwProcessId = 0;
                dwThreadId = 0;
            }
        }

        public struct STARTUPINFO
        {
            public uint cb;
            public string lpReserved;
            public string lpDesktop;
            public string lpTitle;
            public uint dwX;
            public uint dwY;
            public uint dwXSize;
            public uint dwYSize;
            public uint dwXCountChars;
            public uint dwYCountChars;
            public uint dwFillAttribute;
            public uint dwFlags;
            public short wShowWindow;
            public short cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;

            public STARTUPINFO(bool dummy)
            {
                cb = (uint)Marshal.SizeOf(typeof(STARTUPINFO));
                lpReserved = null;
                lpDesktop = null;
                lpTitle = null;
                dwX = 0;
                dwY = 0;
                dwXSize = 0;
                dwYSize = 0;
                dwXCountChars = 0;
                dwYCountChars = 0;
                dwFillAttribute = 0;
                dwFlags = 0;
                wShowWindow = 0;
                cbReserved2 = 0;
                lpReserved2 = IntPtr.Zero;
                hStdInput = IntPtr.Zero;
                hStdOutput = IntPtr.Zero;
                hStdError = IntPtr.Zero;
            }
        }

        public const short SW_NORMAL = 1;

        public const uint STARTF_USESHOWWINDOW = 1;

        [DllImport("kernel32")]
        public static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, UInt32 dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, ref PROCESS_INFORMATION lpProcessInformation);

        [DllImport("advapi32")]
        public static extern bool CreateProcessAsUser(IntPtr hToken, string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, UInt32 dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, ref PROCESS_INFORMATION lpProcessInformation);

        [DllImport("kernel32")]
        public static extern bool CloseHandle(IntPtr hObject);

        [DllImport("user32")]
        public static extern IntPtr GetForegroundWindow();

        [DllImport("user32")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);
    }
}
